package cn.org.seventh.web.common;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Map;

import javax.mail.internet.MimeUtility;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.AbstractView;

/**
 * 二进制文件抽象视图类 该视图类可以输出任意二进制文件
 * 
 * @author <a href="mailto:ji.li@symbio-group.com">Andy</a>
 * @since 2008-6-21 上午12:53:39
 */
public abstract class AbstractBinView extends AbstractView {
	/**
	 * 具体输出动作
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 */
	public abstract InputStream getContentStream(Map model,
			HttpServletRequest request, HttpServletResponse response);

	/**
	 * 文件MIME类型
	 * 
	 * @return
	 */
	public abstract String getContentType();

	/**
	 * 文件名
	 * 
	 * @return
	 */
	public abstract String getFileName();

	/**
	 * 文件长度
	 * 
	 * @return
	 */
	public abstract int getContentLength();

	/**
	 * 缓冲大小
	 * 
	 * @return
	 */
	public abstract int getBufferSize();

	protected final void renderMergedOutputModel(Map model,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		InputStream in;
		int bufferSize;
		String contentType;
		String fileName;
		int contentLength;
		in = new BufferedInputStream(getContentStream(model, request, response));
		bufferSize = getBufferSize();
		contentType = getContentType();
		contentLength = getContentLength();
		fileName = getFileName();
		if (null == in) {
			throw new Exception("no stream to write out!");
		}
		if (bufferSize < 512) {
			bufferSize = 512;
		}
		if (null == contentType || "".endsWith(contentType.trim())) {
			contentType = "application/octet-stream";
		}
		if (null == fileName || "".endsWith(fileName.trim())) {
			fileName = "noname.bin";
		}
		if (contentLength < 0) {
			contentLength = 0;
		}
		response.setContentType(contentType);
		response.setContentLength(contentLength);
		String userAgent = request.getHeader("User-Agent");
		String urlFilename = null;
		if (userAgent != null && userAgent.indexOf("MSIE") != -1) {
			urlFilename = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
		} else {
			urlFilename = MimeUtility.encodeText(fileName);
		}
		response.setHeader("Content-Disposition", "attachment; filename=\""
				+ urlFilename + "\"");
		ServletOutputStream out = response.getOutputStream();
		int temp = -1;
		byte[] buff = new byte[bufferSize];
		while ((temp = in.read(buff, 0, buff.length)) != -1) {
			// System.out.println(temp);
			out.write(buff, 0, temp);
			out.flush(); // 清空缓存
			Thread.yield();
		}
		try {
			in.close();
		} catch (Exception e) {
		} finally {
			in = null;
		}
		try {
			out.close();
		} catch (Exception e) {
		} finally {
			out = null;
		}
	}
}
